﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using OnTheWay.Exceptions;

namespace OnTheWay.Functions
{
    public class FunctionPanel : ContentControl, IFunctioinPanel
    {
        // Fields
        private ObservableCollection<FunctionEntity> mFunctions = new ObservableCollection<FunctionEntity>();

        #region 功能操作

        // Properties
        private FunctionEntity CurFunction { get; set; }

        public ObservableCollection<FunctionEntity> Functions
        {
            get
            {
                return this.mFunctions;
            }
        }

        // Methods
        public bool CloseFunction(FunctionCtrl ctrl)
        {
            if (mRootGrid != null)
            {
                return CloseFunctionStack(ctrl);
            }
            int index = -1;
            for (int i = 0; i < this.mFunctions.Count; i++)
            {
                if (this.mFunctions[i].Ctrl == ctrl)
                {
                    index = i;
                    break;
                }
            }
            if ((index >= 0) || (base.Content == ctrl))
            {
                if (!this.FunctionCloseNotify(ctrl))
                {
                    return false;
                }
                if (index >= 0)
                {
                    this.mFunctions.RemoveAt(index);
                }
                if (base.Content == ctrl)
                {
                    if (this.mFunctions.Count > 0)
                    {
                        base.Content = this.mFunctions[0].Ctrl;
                    }
                    else
                    {
                        base.Content = null;
                    }
                }
            }
            return true;
        }

        private bool FunctionCloseNotify(FunctionCtrl ctrl)
        {
            bool flag = false;
            try
            {
                CancelEventArgs e = new CancelEventArgs();
                ctrl.OnClosing(e);
                if (e.Cancel)
                {
                    return false;
                }
                ctrl.OnClosed(new EventArgs());
                flag = true;
            }
            catch (Exception ex)
            {
                ExceptionHandle.Handle(ex, "FunctionPanel通知关闭（FunctionCloseNotify）出现异常");
            }
            return flag;
        }

        public bool StartFunction(Function function, Assembly assembly)
        {
            try
            {
                //正在功能栈内，不能启动新功能
                if (mRootGrid != null)
                {
                    return false;
                }
                Type type = assembly.GetType(function.Url);
                foreach (FunctionEntity entity in this.mFunctions)
                {
                    if (type == entity.GetType())
                    {
                        this.SwitchFunction(entity.Ctrl);
                        return true;
                    }
                }
                FunctionCtrl ctrl = assembly.CreateInstance(function.Url) as FunctionCtrl;
                ctrl.Title = function.Name;
                this.SwitchFunction(ctrl);
                return true;
            }
            catch (Exception ex)
            {
                ExceptionHandle.Handle(ex, "FunctionPanel启动功能（StartFunction）出现异常");
                return false;
            }
        }

        public bool SwitchFunction(FunctionCtrl ctrl)
        {
            //正在功能栈内，不能启动新功能
            if (mRootGrid != null)
            {
                return false;
            }
            if (base.Content is FunctionCtrl)
            {
                FunctionCtrl content = base.Content as FunctionCtrl;
                if (!(content.IsDurable || this.FunctionCloseNotify(ctrl)))
                {
                    return false;
                }
            }
            if (this.CurFunction != null)
            {
                this.CurFunction.IsCurrent = false;
            }
            this.CurFunction = new FunctionEntity(ctrl, true);
            if (ctrl.IsDurable)
            {
                foreach (FunctionEntity entity in this.mFunctions)
                {
                    if (ctrl.GetType() == entity.Ctrl.GetType())
                    {
                        base.Content = entity.Ctrl;
                        this.CurFunction = entity;
                        this.CurFunction.IsCurrent = true;
                        return true;
                    }
                }
                this.mFunctions.Insert(0, this.CurFunction);
            }
            ctrl.IFunPanel = this;
            base.Content = ctrl;
            return true;
        }

        #endregion

        public void OnClosing(CancelEventArgs e)
        {
            if (OnStackClosing(e))
            {
                return;
            }
            foreach (FunctionEntity entity in this.mFunctions)
            {
                entity.Ctrl.OnClosing(e);
            }
        }

        public void OnClosed(EventArgs e)
        {
            OnStackClosed(e);
            foreach (FunctionEntity entity in this.mFunctions)
            {
                entity.Ctrl.OnClosed(e);
            }
        }

        #region 控件入栈
        /// <summary>
        /// 控件入栈容器（后期使用时候代码生成）
        /// </summary>
        private Grid mRootGrid = null;
        //private List<FunctionCtrl> mltStack = null;
        public void FunctionStackPut(FunctionCtrl fun)
        {
            this.InitializeFunctionStack();
            mRootGrid.Children.Add(fun);
            fun.IFunPanel = this;
        }

        public void FunctionStackPop()
        {
            this.InitializeFunctionStack();
            if (mRootGrid.Children.Count > 1)
            {
                mRootGrid.Children.RemoveAt(mRootGrid.Children.Count - 1);
            }
            //还原
            if (mRootGrid.Children.Count == 1)
            {
                this.Content = mRootGrid.Children[0];
                mRootGrid.Children.Clear();
                mRootGrid = null;
            }
        }

        public bool CloseFunctionStack(FunctionCtrl ctrl)
        {
            if (mRootGrid != null)
            {
                UIElementCollection Children = mRootGrid.Children;
                if (Children.Count > 1 && ctrl == Children[Children.Count - 1])
                {
                    mRootGrid.Children.RemoveAt(Children.Count - 1);
                    //还原
                    if (mRootGrid.Children.Count == 1)
                    {
                        this.Content = mRootGrid.Children[0];
                        mRootGrid.Children.Clear();
                        mRootGrid = null;
                    }
                    return true;
                }
            }
            return false;
        }

        private void InitializeFunctionStack()
        {
            if (mRootGrid == null)
            {
                UIElement content = this.Content as UIElement;
                this.Content = null;
                mRootGrid = new Grid();
                mRootGrid.Children.Add(content);
                this.Content = mRootGrid;
            }
        }

        public void OnStackClosed(EventArgs e)
        {
            if (mRootGrid != null && mRootGrid.Children.Count > 1)
            {
                for (int i = mRootGrid.Children.Count - 1; i > 0; i--)
                {
                    FunctionCtrl fun = mRootGrid.Children[i] as FunctionCtrl;
                    if (fun != null)
                    {
                        fun.OnClosed(e);
                    }
                }
            }
        }

        public bool OnStackClosing(CancelEventArgs e)
        {
            if (mRootGrid != null && mRootGrid.Children.Count > 1)
            {
                for (int i = mRootGrid.Children.Count - 1; i > 0; i--)
                {
                    FunctionCtrl fun = mRootGrid.Children[i] as FunctionCtrl;
                    if (fun != null)
                    {
                        fun.OnClosing(e);
                        if (e.Cancel == true)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }


        #endregion
    }
}

